package com.yida.gwj.expend.outside.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.PageUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.common.domain.mq.MqSendResult;
import com.yida.gwj.common.enums.GwjBusinessFlagType;
import com.yida.gwj.common.enums.StepConfigInfoEnum;
import com.yida.gwj.common.handler.MqSendMessageHandler;
import com.yida.gwj.common.utils.BigDecimalUtils;
import com.yida.gwj.common.utils.GwjEnumUtils;
import com.yida.gwj.expend.outside.annotation.ConfStepConfigCheck;
import com.yida.gwj.expend.outside.config.MaintenanceFundsBusinessConfiguration;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusiness;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusinessAttachment;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusinessBuild;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusinessCommunity;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusinessHouse;
import com.yida.gwj.expend.outside.domain.GwjMaintenanceFundsBusinessInfo;
import com.yida.gwj.expend.outside.domain.dto.AcceptanceReportDTO;
import com.yida.gwj.expend.outside.domain.dto.AllocatedAmountListDTO;
import com.yida.gwj.expend.outside.domain.dto.AllocatedAmountSelectDTO;
import com.yida.gwj.expend.outside.domain.dto.ApplyAppropriateReportDTO;
import com.yida.gwj.expend.outside.domain.dto.CostListDTO;
import com.yida.gwj.expend.outside.domain.dto.GetBusinessDetailDTO;
import com.yida.gwj.expend.outside.domain.dto.GwjMaintenanceFundsBusinessListDTO;
import com.yida.gwj.expend.outside.domain.dto.StepConfigInfoDTO;
import com.yida.gwj.expend.outside.domain.dto.TotalCostShareListDTO;
import com.yida.gwj.expend.outside.domain.message.MaintenanceFundsMqMessageBody;
import com.yida.gwj.expend.outside.domain.message.PreAcceptSubmitMessage;
import com.yida.gwj.expend.outside.domain.request.AcceptanceReportRequest;
import com.yida.gwj.expend.outside.domain.request.AllocatedAmountRequest;
import com.yida.gwj.expend.outside.domain.request.ApplyAppropriateReportRequest;
import com.yida.gwj.expend.outside.domain.request.GwjMaintenanceFundsBusinessListRequest;
import com.yida.gwj.expend.outside.domain.request.HousesUnderBuildRequest;
import com.yida.gwj.expend.outside.domain.request.SaveAppropriateApplyRequest;
import com.yida.gwj.expend.outside.domain.request.ShareEquallyMoneyRequest;
import com.yida.gwj.expend.outside.domain.request.TotalCostShareListRequest;
import com.yida.gwj.expend.outside.enums.BusinessAttachmentServerTypeEnum;
import com.yida.gwj.expend.outside.enums.BusinessAttachmentTypeEnum;
import com.yida.gwj.expend.outside.enums.BusinessStatusEnum;
import com.yida.gwj.expend.outside.enums.FlagStatusEnum;
import com.yida.gwj.expend.outside.enums.MaintenanceFundsErrorEnum;
import com.yida.gwj.expend.outside.enums.SelectFlagEnum;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessAppropriateService;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessAttachmentService;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessCommunityService;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessHouseService;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessInfoService;
import com.yida.gwj.expend.outside.service.IGwjMaintenanceFundsBusinessService;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;

/**
 * 公维金维修资金业务Service业务层处理
 *
 * @author lgp
 * @date 2023-03-09
 */
@Service
public class GwjMaintenanceFundsBusinessAppropriateServiceImpl implements IGwjMaintenanceFundsBusinessAppropriateService {

    private final Logger log = LoggerFactory.getLogger(GwjMaintenanceFundsBusinessAppropriateServiceImpl.class);
    private final GwjBusinessFlagType businessFlagType = GwjBusinessFlagType.EXPEND_OUTSIDE_APPROPRIATE;
    @Autowired
    private IGwjMaintenanceFundsBusinessInfoService maintenanceFundsBusinessInfoService;
    @Autowired
    private IGwjMaintenanceFundsBusinessHouseService maintenanceFundsBusinessHouseService;
    @Autowired
    private IGwjMaintenanceFundsBusinessCommunityService maintenanceFundsBusinessCommunityService;
    @Autowired
    private IGwjMaintenanceFundsBusinessService maintenanceFundsBusinessService;
    @Autowired
    private MaintenanceFundsBusinessConfiguration maintenanceFundsBusinessConfiguration;
    @Autowired
    private IGwjMaintenanceFundsBusinessAttachmentService maintenanceFundsBusinessAttachmentService;
    @Autowired
    private MqSendMessageHandler mqSendMessageHandler;

    // 缴款面积类型 1:实测面积；2：预测面积 20230719
    private static final Integer[] depositSizeType = {1, 2};

    /**
     * 查询公维金拨付申请业务列表
     *
     * @param maintenanceFundsBusinessListRequest 公维金维修资金业务
     * @return 公维金维修资金业务
     */
    @Override
    public List<GwjMaintenanceFundsBusinessListDTO> getGwjMaintenanceFundsBusinessList(GwjMaintenanceFundsBusinessListRequest maintenanceFundsBusinessListRequest) {
        return maintenanceFundsBusinessService.getGwjMaintenanceFundsBusinessList(maintenanceFundsBusinessListRequest);
    }

    /**
     * 分摊金额-已选择
     *
     * @param allocatedAmountAppropriateRequest 分摊金额请求
     * @return AllocatedAmountSelectDTO
     */
    @Override
    public AllocatedAmountSelectDTO allocatedAmountList(AllocatedAmountRequest allocatedAmountAppropriateRequest) {
        return maintenanceFundsBusinessService.allocatedAmountList(allocatedAmountAppropriateRequest, GwjBusinessFlagType.EXPEND_OUTSIDE_APPROPRIATE);
    }

    /**
     * 分摊金额-未选中房屋列表
     *
     * @param allocatedAmountRequest 查询未选中房屋列表请求
     * @return 公维金维修资金业务
     */
    @Override
    public List<GwjMaintenanceFundsBusinessHouse> allocatedAmountCancelList(AllocatedAmountRequest allocatedAmountRequest) {
        return maintenanceFundsBusinessService.allocatedAmountCancelList(allocatedAmountRequest);
    }

    /**
     * 获取验收报告
     *
     * @param bizId 业务标识
     * @return {@link AcceptanceReportDTO}
     */
    @Override
    public AcceptanceReportDTO getAcceptanceReport(Long bizId) {
        GwjMaintenanceFundsBusinessInfo gwjMaintenanceFundsBusinessAppropriateInfo = maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessAppropriateInfo)) {
            return null;
        }
        GwjMaintenanceFundsBusiness gwjMaintenanceFundsBusinessAppropriate = maintenanceFundsBusinessService.selectGwjMaintenanceFundsBusinessByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessAppropriate)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_CHANGE_SCHEME) + "GwjMaintenanceFundsBusiness为空");
        }
        GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = maintenanceFundsBusinessAttachmentService.getGwjMaintenanceFundsBusinessAttachment(new GwjMaintenanceFundsBusinessAttachment() {
            {
                setServerIdentification(gwjMaintenanceFundsBusinessAppropriate.getServerIdentification());
                setServerType(BusinessAttachmentServerTypeEnum.ACCEPTANCE_REPORT.getCode());
                setType(BusinessAttachmentTypeEnum.REPORT.getCode());
            }
        });
        return new AcceptanceReportDTO() {
            {
                setMaintenanceItems(gwjMaintenanceFundsBusinessAppropriateInfo.getMaintenanceItems());
                setConstructionUnitName(gwjMaintenanceFundsBusinessAppropriateInfo.getConstructionUnit());
                setApplicationUnitName(gwjMaintenanceFundsBusinessAppropriateInfo.getApplicationUnitName());
                setProjectBudgetAmount(gwjMaintenanceFundsBusinessAppropriateInfo.getProjectBudgetAmount());
                setProjectBudgetAmountChar(BigDecimalUtils.toChinese(gwjMaintenanceFundsBusinessAppropriateInfo.getProjectBudgetAmount().toString()));
                setAcceptancePersonnelList(new ArrayList<AcceptanceReportRequest.AcceptancePersonnel>());
                if (ObjectUtil.isNotNull(maintenanceFundsBusinessAttachment)) {
                    AcceptanceReportRequest acceptanceReportRequest = JSONUtil.toBean(maintenanceFundsBusinessAttachment.getContent(), AcceptanceReportRequest.class);
                    setDesigner(acceptanceReportRequest.getDesigner());
                    setControlUnit(acceptanceReportRequest.getControlUnit());
                    setProjectOverview(acceptanceReportRequest.getProjectOverview());
                    setAcceptanceContent(acceptanceReportRequest.getAcceptanceContent());
                    setAcceptanceAmount(acceptanceReportRequest.getAcceptanceAmount());
                    setAcceptanceConclusion(acceptanceReportRequest.getAcceptanceConclusion());
                    setConstructionUnit(acceptanceReportRequest.getConstructionUnit());
                    setAttachmentId(maintenanceFundsBusinessAttachment.getAttachmentId());
                    if (ObjectUtil.isNotNull(acceptanceReportRequest.getAcceptancePersonnelList())) {
                        setAcceptancePersonnelList(acceptanceReportRequest.getAcceptancePersonnelList());
                    }
                    setConstructionUnit(acceptanceReportRequest.getConstructionUnit());
                    setCommencementTime(acceptanceReportRequest.getCommencementTime());
                    setSaveTime(acceptanceReportRequest.getSaveTime());
                }
            }
        };
    }

    /**
     * 保存拨付申请业务
     *
     * @param saveAppropriateApplyRequest 保存拨付申请业务请求
     * @return int
     */
    @ConfStepConfigCheck(bizId = "#saveAppropriateApplyRequest.bizId", stepConfigInfo = {StepConfigInfoEnum.SAVE}, businessStatus = {BusinessStatusEnum.SAVE, BusinessStatusEnum.RETREAT_PARTS})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveAppropriateApply(SaveAppropriateApplyRequest saveAppropriateApplyRequest) {
        GwjMaintenanceFundsBusinessInfo gwjInfo = maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(saveAppropriateApplyRequest.getBizId());
        if (ObjectUtil.isNull(gwjInfo)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SAVE_APPROPRIATE_APPLY_FAL) + "查询GwjMaintenanceFundsBusinessAppropriateInfo异常");
        }
        int compareTo = gwjInfo.getProjectBudgetAmount().compareTo(saveAppropriateApplyRequest.getTotalSettlementAmount());
        if (compareTo < 0) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SAVE_APPROPRIATE_APPLY_FAL) + "决算总金额必须小于或等于工程预算");
        }
        int compare = gwjInfo.getBudgetAppropriationAmount().compareTo(saveAppropriateApplyRequest.getTotalSettlementAmount());
        if (compare > 0) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SAVE_APPROPRIATE_APPLY_FAL) + "决算总金额必须大于或等于预算拨款金额");
        }
        // 保存business表
        if (ObjectUtil.isNull(maintenanceFundsBusinessService.updateGwjMaintenanceFundsBusiness(new GwjMaintenanceFundsBusiness() {
            {
                setPhone(saveAppropriateApplyRequest.getPhone());
                setBizId(saveAppropriateApplyRequest.getBizId());
                setBizFlagId(saveAppropriateApplyRequest.getBizFlagId());
                setContacts(saveAppropriateApplyRequest.getContacts());
                setCurrentOperId(SecurityUtils.getUserId());
                setCurrentOperName(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());// 外网redis内存粹的名称为实际用户名称
            }
        }))) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SAVE_APPROPRIATE_APPLY_FAL) + "更新GwjMaintenanceFundsBusinessAppropriate异常");
        }
        // 计算第二期款项 = 决算总金额 - 预算拨出总金额
        BigDecimal secondAppropriationAmount = saveAppropriateApplyRequest.getTotalSettlementAmount().subtract(gwjInfo.getBudgetAppropriationAmount());
        GwjMaintenanceFundsBusinessInfo gwjMaintenanceFundsBusinessAppropriateInfo = new GwjMaintenanceFundsBusinessInfo() {
            {
                setBizId(saveAppropriateApplyRequest.getBizId());
                setRepairCompletionDate(saveAppropriateApplyRequest.getRepairCompletionDate());
                setApplicationUnitName(saveAppropriateApplyRequest.getApplicationUnitName());
                setSecondAppropriationAmount(secondAppropriationAmount);
                setTotalSettlementAmount(saveAppropriateApplyRequest.getTotalSettlementAmount());
            }
        };
        // 保存info表
        if (ObjectUtil.isNull(maintenanceFundsBusinessInfoService.updateGwjMaintenanceFundsBusinessInfo(gwjMaintenanceFundsBusinessAppropriateInfo))) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SAVE_APPROPRIATE_APPLY_FAL) + "更新GwjMaintenanceFundsBusinessInfo异常");
        }
        return FlagStatusEnum.SUC.getCode();
    }

    /**
     * 获取gwj维修基金业务详细信息
     *
     * @param bizId 业务标识
     * @return {@link GetBusinessDetailDTO}
     */
    @Override
    public GetBusinessDetailDTO getDetailMessage(Long bizId) {
        return maintenanceFundsBusinessService.getDetailMessage(bizId);
    }

    /**
     * 分摊金额-选中房屋
     *
     * @param allocatedAmountRequest
     * @return AllocatedAmountSelectDTO
     */
    @ConfStepConfigCheck(bizId = "#allocatedAmountRequest.bizId", stepConfigInfo = {StepConfigInfoEnum.SAVE}, businessStatus = {BusinessStatusEnum.SAVE, BusinessStatusEnum.RETREAT_PARTS})
    @Override
    public int allocatedAmountArrange(AllocatedAmountRequest allocatedAmountRequest) {
        return maintenanceFundsBusinessService.allocatedAmountArrange(allocatedAmountRequest);
    }

    /**
     * 分摊金额-取消选中房屋
     *
     * @param allocatedAmountRequest
     * @return AllocatedAmountSelectDTO
     */
    @Override
    public int allocatedAmountCancel(AllocatedAmountRequest allocatedAmountRequest) {
        return maintenanceFundsBusinessService.allocatedAmountCancel(allocatedAmountRequest);
    }

    // @ConfStepConfigCheck(bizId = "#shareEquallyMoneyRequest.bizId", stepConfigInfo = {StepConfigInfoEnum.SAVE,
    // StepConfigInfoEnum.SUBMIT}, businessStatus = {BusinessStatusEnum.SAVE, BusinessStatusEnum.RETREAT_PARTS})
    // @Transactional(rollbackFor = Exception.class)
    // @Override
    // public int shareEquallyMoney(ShareEquallyMoneyRequest shareEquallyMoneyRequest) {
    // GwjMaintenanceFundsBusiness gwjMaintenanceFundsBusiness =
    // maintenanceFundsBusinessService.selectGwjMaintenanceFundsBusinessByBusinessId(shareEquallyMoneyRequest.getBizId());
    // if (ObjectUtil.equals(gwjMaintenanceFundsBusiness.getSupplementFlag(), FlagStatusEnum.SUC)) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) +
    // "二次补件不可更改分摊金额");
    // }
    // GwjMaintenanceFundsBusinessInfo maintenanceFundsBusinessInfo =
    // maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(shareEquallyMoneyRequest.getBizId());
    // if (ObjectUtil.isNull(maintenanceFundsBusinessInfo)) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) +
    // "GwjMaintenanceFundsBusinessInfo为空");
    // }
    // if (NumberUtil.equals(BigDecimal.ZERO, maintenanceFundsBusinessInfo.getTotalInvolvedArea())) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) +
    // "分摊总面积为0");
    // }
    // if (NumberUtil.equals(BigDecimal.ZERO, maintenanceFundsBusinessInfo.getTotalSettlementAmount())) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) +
    // "请先填写决算总金额");
    // }
    // List<GwjMaintenanceFundsBusinessHouse> maintenanceFundsBusinessHouseList =
    // maintenanceFundsBusinessHouseService.selectGwjMaintenanceFundsBusinessHouseList(new
    // GwjMaintenanceFundsBusinessHouse() {
    // {
    // setSelectFlag(SelectFlagEnum.SELECT.getCode());
    // setBizId(shareEquallyMoneyRequest.getBizId());
    // }
    // });
    // if (CollectionUtil.isEmpty(maintenanceFundsBusinessHouseList)) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) +
    // "List<GwjMaintenanceFundsBusinessHouse>为空");
    // }
    // AtomicReference<BigDecimal> totalAllocationMoney = new AtomicReference<>(BigDecimal.ZERO);
    // maintenanceFundsBusinessHouseList.forEach(house -> {
    // house.setLackMoney(BigDecimal.ZERO);
    // house.setSelfRaiseMoney(BigDecimal.ZERO);
    // BigDecimal allocationMoney = BigDecimal.ZERO;
    // // 按面积计算公式:(房屋面积/总面积)*分摊金额,截取小数点后两位,剩下的进行补差额
    // if (ObjectUtil.equal(StandardTypeEnum.AREA.getCode(), shareEquallyMoneyRequest.getStandardType())) {
    // if (NumberUtil.equals(maintenanceFundsBusinessInfo.getTotalInvolvedArea(), BigDecimal.ZERO)) {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) +
    // "涉及总面积不能为0");
    // }
    // allocationMoney = NumberUtil.mul(NumberUtil.div(ObjectUtil.equal(house.getActualSize(), BigDecimal.ZERO) ?
    // house.getForecastSize() : house.getActualSize(), maintenanceFundsBusinessInfo.getTotalInvolvedArea()),
    // maintenanceFundsBusinessInfo.getTotalSettlementAmount());
    // house.setAllocationMoney(allocationMoney);
    // }
    // // 按户数计算公式:分摊金额/户数,截取小数点后两位,剩下的进行补差额
    // if (ObjectUtil.equal(StandardTypeEnum.OWNER.getCode(), shareEquallyMoneyRequest.getStandardType())) {
    // allocationMoney = NumberUtil.div(maintenanceFundsBusinessInfo.getTotalSettlementAmount(),
    // maintenanceFundsBusinessInfo.getTotalHouseholds(), 2, RoundingMode.HALF_UP);
    // house.setAllocationMoney(allocationMoney);
    // }
    // house.setTotalAllocationMoney(allocationMoney);
    // house.setActualAllocationMoney(allocationMoney);
    // totalAllocationMoney.set(NumberUtil.add(totalAllocationMoney.get(), allocationMoney));
    // });
    // Optional.ofNullable(maintenanceFundsBusinessInfoService.updateGwjMaintenanceFundsBusinessInfoByBusinessId(new
    // GwjMaintenanceFundsBusinessInfo() {
    // {
    // setActualAllocationAmount(totalAllocationMoney.get());
    // setTotalAllocatedSettlementAmount(totalAllocationMoney.get());
    // setBizId(maintenanceFundsBusinessInfo.getBizId());
    // setCalculationStandard(shareEquallyMoneyRequest.getStandardType());
    // }
    // })).<ServiceException>orElseThrow(() -> {
    // throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) +
    // "GwjMaintenanceFundsBusinessInfo更新失败");
    // });
    // return
    // maintenanceFundsBusinessHouseService.updateBatchGwjMaintenanceFundsBusinessHouse(maintenanceFundsBusinessHouseList);
    // }

    @ConfStepConfigCheck(bizId = "#shareEquallyMoneyRequest.bizId", stepConfigInfo = {StepConfigInfoEnum.SAVE, StepConfigInfoEnum.SUBMIT}, businessStatus = {BusinessStatusEnum.SAVE, BusinessStatusEnum.RETREAT_PARTS})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int shareEquallyMoney(ShareEquallyMoneyRequest shareEquallyMoneyRequest) {
        GwjMaintenanceFundsBusiness gwjMaintenanceFundsBusiness = maintenanceFundsBusinessService.selectGwjMaintenanceFundsBusinessByBusinessId(shareEquallyMoneyRequest.getBizId());
        if (ObjectUtil.equals(gwjMaintenanceFundsBusiness.getSupplementFlag(), FlagStatusEnum.SUC)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) + "二次补件不可更改分摊金额");
        }
        GwjMaintenanceFundsBusinessInfo maintenanceFundsBusinessInfo = maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(shareEquallyMoneyRequest.getBizId());
        if (ObjectUtil.isNull(maintenanceFundsBusinessInfo)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) + "GwjMaintenanceFundsBusinessInfo为空");
        }
        if (NumberUtil.equals(BigDecimal.ZERO, maintenanceFundsBusinessInfo.getTotalInvolvedArea())) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) + "分摊总面积为0");
        }
        if (NumberUtil.equals(BigDecimal.ZERO, maintenanceFundsBusinessInfo.getTotalSettlementAmount())) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) + "请先填写决算总金额");
        }
        List<GwjMaintenanceFundsBusinessHouse> maintenanceFundsBusinessHouseList = maintenanceFundsBusinessHouseService.selectGwjMaintenanceFundsBusinessHouseList(new GwjMaintenanceFundsBusinessHouse() {
            {
                setSelectFlag(SelectFlagEnum.SELECT.getCode());
                setBizId(shareEquallyMoneyRequest.getBizId());
                setSelectFlag(1);// 增加已选中房屋判断 hmh
            }
        });
        if (CollectionUtil.isEmpty(maintenanceFundsBusinessHouseList)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) + "List<GwjMaintenanceFundsBusinessHouse>为空");
        }
        AtomicReference<BigDecimal> totalAllocationMoney = new AtomicReference<>(BigDecimal.ZERO);
        // 涉及总面积为0
        if (NumberUtil.equals(maintenanceFundsBusinessInfo.getTotalInvolvedArea(), BigDecimal.ZERO)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) + "涉及总面积不能为0");
        }
        Integer standardType = shareEquallyMoneyRequest.getStandardType();
        // 提示信息
        StringBuffer sb = new StringBuffer();
        maintenanceFundsBusinessHouseList.forEach(house -> {
            house.setLackMoney(BigDecimal.ZERO);
            house.setSelfRaiseMoney(BigDecimal.ZERO);
            BigDecimal allocationMoney = BigDecimal.ZERO;
            // 缴款面积
            BigDecimal depositSize = BigDecimal.ZERO;
            // 按面积计算公式:(房屋面积/总面积)*分摊金额,截取小数点后两位,剩下的进行补差额
            // if (ObjectUtil.equal(StandardTypeEnum.AREA.getCode(), shareEquallyMoneyRequest.getStandardType())) {
            // if (NumberUtil.equals(maintenanceFundsBusinessInfo.getTotalInvolvedArea(), BigDecimal.ZERO)) {
            // throw new
            // ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) +
            // "涉及总面积不能为0");
            // }
            // allocationMoney = NumberUtil.mul(NumberUtil.div(ObjectUtil.equal(house.getActualSize(), BigDecimal.ZERO)
            // ? house.getForecastSize() : house.getActualSize(), maintenanceFundsBusinessInfo.getTotalInvolvedArea()),
            // maintenanceFundsBusinessInfo.getProjectBudgetAmount());
            // house.setAllocationMoney(allocationMoney);
            // }
            // 20230717
            // 实测面积（现房）
            BigDecimal actualSize = StringUtils.isNull(house.getActualSize()) ? BigDecimal.ZERO : house.getActualSize();
            // 预测面积（期房）
            BigDecimal forecastSize = StringUtils.isNull(house.getForecastSize()) ? BigDecimal.ZERO : house.getForecastSize();
            // 非公用户进行中断
            if (BigDecimal.ZERO.compareTo(actualSize) == 0 && BigDecimal.ZERO.compareTo(forecastSize) == 0 && house.getPublicFlag() == 0) {
                throw new ServiceException("房屋编号：" + house.getHouseCode() + "现房面积和期房面积均为空，无法计算！");
            }
            if (ArrayUtils.contains(depositSizeType, shareEquallyMoneyRequest.getStandardType())) {
                // 按实际面积取值(实测面积)
                if (1 == standardType) {
                    // depositSize = StringUtils.isNull(house.getActualSize()) ? BigDecimal.ZERO :
                    // house.getActualSize();
                    // 优先判断现房面积
                    depositSize = BigDecimal.ZERO.compareTo(actualSize) == 0 ? forecastSize : actualSize;
                }
                // 按预期面积取值(预测面积)
                if (2 == standardType) {

                    // depositSize = StringUtils.isNull(house.getForecastSize()) ? BigDecimal.ZERO :
                    // house.getForecastSize();
                    // 优先判断期房面积
                    depositSize = BigDecimal.ZERO.compareTo(forecastSize) == 0 ? actualSize : forecastSize;
                }
                // allocationMoney = NumberUtil.mul(NumberUtil.div(depositSize,
                // maintenanceFundsBusinessInfo.getTotalInvolvedArea()),
                // maintenanceFundsBusinessInfo.getProjectBudgetAmount());
                // 拨付时候这里拿决算金额 20230719 hmh
                allocationMoney = NumberUtil.mul(NumberUtil.div(depositSize, maintenanceFundsBusinessInfo.getTotalInvolvedArea()), maintenanceFundsBusinessInfo.getTotalSettlementAmount());
                house.setAllocationMoney(allocationMoney);

            }
            // 按户数计算公式:分摊金额/户数,截取小数点后两位,剩下的进行补差额
            if (ObjectUtil.equal(3, shareEquallyMoneyRequest.getStandardType())) {
                // allocationMoney = NumberUtil.div(maintenanceFundsBusinessInfo.getProjectBudgetAmount(),
                // maintenanceFundsBusinessInfo.getTotalHouseholds(), 2, RoundingMode.HALF_UP);
                // 拨付时候这里拿决算金额 20230719 hmh
                allocationMoney = NumberUtil.div(maintenanceFundsBusinessInfo.getTotalSettlementAmount(), maintenanceFundsBusinessInfo.getTotalHouseholds(), 2, RoundingMode.HALF_UP);
                house.setAllocationMoney(allocationMoney);
                // 按户优先现房
                depositSize = BigDecimal.ZERO.compareTo(actualSize) == 0 ? forecastSize : actualSize;
            }
            // 设置缴款面积
            allocationMoney.setScale(2, RoundingMode.HALF_UP);
            house.setDepositSize(depositSize);
            house.setTotalAllocationMoney(allocationMoney);
            house.setActualAllocationMoney(allocationMoney);
            // totalAllocationMoney.set(NumberUtil.add(totalAllocationMoney.get(),
            // allocationMoney,2,RoundingMode.HALF_UP));
            // totalAllocationMoney.set(NumberUtil.add(totalAllocationMoney.get(), allocationMoney));
            // totalAllocationMoney.set(NumberUtil.add(allocationMoney,totalAllocationMoney.get().));
            // 20230802 判断余额是否不足,余额小于实际分摊金额进行提示
            BigDecimal currentMoney = house.getCurrentMoney();
            if (currentMoney.compareTo(allocationMoney) == -1) {
                sb.append("房屋编号：").append(house.getHouseCode()).append("，实际分摊金额[").append(house.getActualAllocationMoney()).append("]").append("大于可用余额[").append(currentMoney).append("]").append("\n\r");
            }
            // 计算后累加保留2位小数，防止精度丢失
            totalAllocationMoney.set(totalAllocationMoney.get().add(allocationMoney).setScale(2, RoundingMode.HALF_UP));
        });
        // 20230802 查询是否存在提示信息
        if (StringUtils.isNotEmpty(sb) || sb.length() > 0) {
            throw new ServiceException(sb.toString());
        }
        Optional.ofNullable(maintenanceFundsBusinessInfoService.updateGwjMaintenanceFundsBusinessInfoByBusinessId(new GwjMaintenanceFundsBusinessInfo() {
            {
                setActualAllocationAmount(totalAllocationMoney.get());
                setTotalAllocatedSettlementAmount(totalAllocationMoney.get());
                setBizId(maintenanceFundsBusinessInfo.getBizId());
                setCalculationStandard(shareEquallyMoneyRequest.getStandardType());
            }
        })).<ServiceException>orElseThrow(() -> {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.SHARE_EQUALLY_MONEY) + "GwjMaintenanceFundsBusinessInfo更新失败");
        });
        return maintenanceFundsBusinessHouseService.updateBatchGwjMaintenanceFundsBusinessHouse(maintenanceFundsBusinessHouseList);
    }

    /**
     * 修改平摊金额
     *
     * @param shareEquallyMoneyRequest
     * @return AllocatedAmountSelectDTO
     */
    @Override
    public int shareEquallyMoneyUpdate(ShareEquallyMoneyRequest shareEquallyMoneyRequest) {
        return maintenanceFundsBusinessService.shareEquallyMoneyUpdate(shareEquallyMoneyRequest);
    }

    /**
     * 获取申请拨付报告
     *
     * @param bizId 业务标识
     * @return {@link AcceptanceReportDTO}
     */
    @Override
    public ApplyAppropriateReportDTO getApplyAppropriateReport(Long bizId) {
        GwjMaintenanceFundsBusiness gwjMaintenanceFundsBusiness = maintenanceFundsBusinessService.selectGwjMaintenanceFundsBusinessByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusiness)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_APPROPRIATE_APPLY_REPORT) + "gwjMaintenanceFundsBusiness为空");
        }
        GwjMaintenanceFundsBusinessInfo gwjMaintenanceFundsBusinessInfo = maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessInfo)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_APPROPRIATE_APPLY_REPORT) + "gwjMaintenanceFundsBusiness为空");
        }
        GwjMaintenanceFundsBusinessCommunity gwjMaintenanceFundsBusinessCommunity = maintenanceFundsBusinessCommunityService.selectGwjMaintenanceFundsBusinessCommunityByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessCommunity)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_APPROPRIATE_APPLY_REPORT) + "gwjMaintenanceFundsBusinessCommunity为空");
        }
        GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = maintenanceFundsBusinessAttachmentService.getGwjMaintenanceFundsBusinessAttachment(new GwjMaintenanceFundsBusinessAttachment() {
            {
                setServerIdentification(gwjMaintenanceFundsBusiness.getServerIdentification());
                setServerType(BusinessAttachmentServerTypeEnum.APPLICATION_APPROPRIATE_REPORT.getCode());
                setType(BusinessAttachmentTypeEnum.REPORT.getCode());
            }
        });

        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessInfo.getBudgetAppropriationAmount())) {
            gwjMaintenanceFundsBusinessInfo.setBudgetAppropriationAmount(BigDecimal.ZERO);
        }
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessInfo.getSecondAppropriationAmount())) {
            gwjMaintenanceFundsBusinessInfo.setSecondAppropriationAmount(BigDecimal.ZERO);
        }
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusinessInfo.getTotalSettlementAmount())) {
            gwjMaintenanceFundsBusinessInfo.setTotalSettlementAmount(BigDecimal.ZERO);
        }
        return new ApplyAppropriateReportDTO() {
            {
                setCommunityName(gwjMaintenanceFundsBusinessCommunity.getCommunityName());
                setRepairCompletionDate(gwjMaintenanceFundsBusinessInfo.getRepairCompletionDate());
                setMaintenanceItems(gwjMaintenanceFundsBusinessInfo.getMaintenanceItems());
                setTotalSettlementAmount(gwjMaintenanceFundsBusinessInfo.getTotalSettlementAmount());
                setBudgetAppropriationAmount(gwjMaintenanceFundsBusinessInfo.getBudgetAppropriationAmount());
                setApplicationUnitName(gwjMaintenanceFundsBusinessInfo.getApplicationUnitName());
                setSecondAppropriationAmount(gwjMaintenanceFundsBusinessInfo.getSecondAppropriationAmount());
                setPayeeName(gwjMaintenanceFundsBusinessInfo.getPayeeName());
                setBankDeposit(gwjMaintenanceFundsBusinessInfo.getBankDeposit());
                setCollectionAccount(gwjMaintenanceFundsBusinessInfo.getCollectionAccount());
                setTotalHouseholds(gwjMaintenanceFundsBusinessInfo.getTotalHouseholds());
                setApplicationUnitName(gwjMaintenanceFundsBusinessInfo.getApplicationUnitName());
                setBudgetAppropriationAmountChar(BigDecimalUtils.toChinese(gwjMaintenanceFundsBusinessInfo.getBudgetAppropriationAmount().toString()));
                setSecondAppropriationAmountChar(BigDecimalUtils.toChinese(gwjMaintenanceFundsBusinessInfo.getSecondAppropriationAmount().toString()));
                setTotalSettlementAmountChar(BigDecimalUtils.toChinese(gwjMaintenanceFundsBusinessInfo.getTotalSettlementAmount().toString()));
                if (ObjectUtil.isNotNull(maintenanceFundsBusinessAttachment)) {
                    ApplyAppropriateReportRequest applyAppropriateReportRequest = JSONUtil.toBean(maintenanceFundsBusinessAttachment.getContent(), ApplyAppropriateReportRequest.class);
                    setAcceptanceUnit(applyAppropriateReportRequest.getAcceptanceUnit());
                    setAcceptanceReportIssuingUnit(applyAppropriateReportRequest.getAcceptanceReportIssuingUnit());
                    setBudgetAppropriationTime(applyAppropriateReportRequest.getBudgetAppropriationTime());
                    setPublicityStartTime(applyAppropriateReportRequest.getPublicityStartTime());
                    setPublicityEndTime(applyAppropriateReportRequest.getPublicityEndTime());
                    setSaveTime(applyAppropriateReportRequest.getSaveTime());
                    setPublicityPlace(applyAppropriateReportRequest.getPublicityPlace());
                    setAttachmentId(maintenanceFundsBusinessAttachment.getAttachmentId());
                }
            }
        };
    }

    /**
     * 预受理提交
     *
     * @param bizId 业务标识
     * @return int
     */
    @ConfStepConfigCheck(bizId = "#bizId", stepConfigInfo = {StepConfigInfoEnum.SUBMIT}, businessStatus = {BusinessStatusEnum.SAVE, BusinessStatusEnum.RETREAT_PARTS})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int preSubmit(Long bizId) {
        try {
            PreAcceptSubmitMessage preAcceptSubmitMessage = maintenanceFundsBusinessService.preAcceptSubmit(bizId, BusinessAttachmentServerTypeEnum.getAppropriateServerTypeList());
            String tag = maintenanceFundsBusinessConfiguration.appropriateTagProperties().getPreAcceptSubmit();
            MqSendResult mqSendResult = mqSendMessageHandler.syncSend(new MaintenanceFundsMqMessageBody() {
                {
                    setJsonMsg(JSONUtil.toJsonStr(preAcceptSubmitMessage));
                    setServerIdentification(preAcceptSubmitMessage.getMaintenanceFundsBusiness().getServerIdentification());
                }
            }, new MaintenanceFundsBusinessConfiguration.MaintenanceFundsBusinessAppropriateSendRequest(tag, null));
            if (mqSendResult.isSuccess()) {
                return FlagStatusEnum.SUC.getCode();
            } else {
                throw new ServiceException("公维金资金申请提交数据到内网MQ异常");
            }
        } catch (ServiceException e) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.APPROPRIATE_PRE_ACCEPT_SUBMIT) + e.getMessage());
        }
    }

    /**
     * 查询决算费用分摊清册
     *
     * @param bizId 业务标识
     * @return int
     */
    @Override
    public TotalCostShareListDTO costList(Long bizId, BusinessAttachmentServerTypeEnum businessAttachmentServerTypeEnum) {
        List<CostListDTO> costListDtoS = maintenanceFundsBusinessService.costList(bizId);
        if (ObjectUtil.isNull(costListDtoS)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_TOTAL0_COST_SHARE_LIST) + "costListDtoS为空");
        }
        GwjMaintenanceFundsBusiness gwjMaintenanceFundsBusiness = maintenanceFundsBusinessService.selectGwjMaintenanceFundsBusinessByBusinessId(bizId);
        if (ObjectUtil.isNull(gwjMaintenanceFundsBusiness)) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.GET_TOTAL0_COST_SHARE_LIST) + "gwjMaintenanceFundsBusiness为空");
        }
        GwjMaintenanceFundsBusinessInfo gwjMaintenanceFundsBusinessInfo = maintenanceFundsBusinessInfoService.selectGwjMaintenanceFundsBusinessInfoByBusinessId(bizId);
        GwjMaintenanceFundsBusinessCommunity gwjMaintenanceFundsBusinessCommunity = maintenanceFundsBusinessCommunityService.selectGwjMaintenanceFundsBusinessCommunityByBusinessId(bizId);
        GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = maintenanceFundsBusinessAttachmentService.getGwjMaintenanceFundsBusinessAttachment(new GwjMaintenanceFundsBusinessAttachment() {
            {
                setServerIdentification(gwjMaintenanceFundsBusiness.getServerIdentification());
                setServerType(businessAttachmentServerTypeEnum.getCode());
                setType(BusinessAttachmentTypeEnum.REPORT.getCode());
            }
        });
        LocalDate saveTime = null;
        Long attachmentId = null;
        if (ObjectUtil.isNotNull(maintenanceFundsBusinessAttachment)) {
            TotalCostShareListRequest totalCostShareListRequest = JSONUtil.toBean(maintenanceFundsBusinessAttachment.getContent(), TotalCostShareListRequest.class);
            if (ObjectUtil.isNotNull(totalCostShareListRequest.getSaveContentList())) {
                for (CostListDTO costListDTO : costListDtoS) {
                    for (int i = 0; i < totalCostShareListRequest.getSaveContentList().size(); i++) {
                        if (ObjectUtil.equal(costListDTO.getHouseCode(), totalCostShareListRequest.getSaveContentList().get(i).getHouseCode())) {
                            costListDTO.setRemark(totalCostShareListRequest.getSaveContentList().get(i).getRemark());
                        }
                    }
                }
                saveTime = totalCostShareListRequest.getSaveTime();
            }
            attachmentId = maintenanceFundsBusinessAttachment.getAttachmentId();
        }
        LocalDate finalSaveTime = saveTime;
        Long finalAttachmentId = attachmentId;
        return new TotalCostShareListDTO() {
            {
                setCommunityName(gwjMaintenanceFundsBusinessCommunity.getCommunityName());
                setMaintenanceItems(gwjMaintenanceFundsBusinessInfo.getMaintenanceItems());
                setTotalSettlementAmount(gwjMaintenanceFundsBusinessInfo.getTotalSettlementAmount());
                setApplicationUnitName(gwjMaintenanceFundsBusinessInfo.getApplicationUnitName());
                setTableDataInfo(PageUtils.getDataTable(costListDtoS));
                setSaveTime(finalSaveTime);
                setAttachmentId(finalAttachmentId);
            }
        };
    }

    /**
     * 获取已选中楼栋信息
     *
     * @param bizId
     * @return 获取已选中楼栋信息
     */
    @Override
    public List<GwjMaintenanceFundsBusinessBuild> getSelectBuilds(Long bizId) {
        return maintenanceFundsBusinessService.getSelectBuilds(bizId);
    }

    /**
     * 获取楼栋下房屋信息
     *
     * @param housesUnderBuildRequest
     * @return 楼栋下房屋信息
     */
    @Override
    public List<GwjMaintenanceFundsBusinessHouse> getHouseList(HousesUnderBuildRequest housesUnderBuildRequest) {
        return maintenanceFundsBusinessService.getHouseList(housesUnderBuildRequest);
    }

    /**
     * 导出房屋数据
     *
     * @param allocatedAmountRequest
     * @return 楼栋下房屋信息
     */
    @Override
    public List<AllocatedAmountListDTO> exportHouseList(AllocatedAmountRequest allocatedAmountRequest) {
        return maintenanceFundsBusinessService.exportHouseList(allocatedAmountRequest);
    }

    @Override
    public StepConfigInfoDTO getStepConfigInfo() {
        return maintenanceFundsBusinessService.getStepConfigInfo(businessFlagType);
    }
}
